import Head from 'next/head';
import TableOptionsTable from '../../../components/prop-tables/TableOptionsTable';
import StateOptionsTable from '../../../components/prop-tables/StateOptionsTable';
import EnableExample from '../../../examples/enable-row-selection';
import EnableSwitchExample from '../../../examples/enable-row-selection-switch';
import SingleExample from '../../../examples/single-row-selection';
import ManualExample from '../../../examples/manual-selection';
import CustomizeExample from '../../../examples/customize-row-selection';

<Head>
  <title>Row Selection Feature Guide - Mantine React Table Docs</title>
  <meta
    name="description"
    content="How to add and customize row selection checkboxes in Mantine React Table"
  />
</Head>

## Row Selection Feature Guide

Mantine React Table has a built-in row-selection feature and makes it easy to manage the selection state yourself. This guide will walk you through how to enable row selection and how to customize the selection behavior.

### Relevant Table Options

<TableOptionsTable
  onlyOptions={
    new Set([
      'enableBatchRowSelection',
      'enableMultiRowSelection',
      'enableRowSelection',
      'enableSelectAll',
      'enableSubRowSelection',
      'getRowId',
      'mantineSelectAllCheckboxProps',
      'mantineSelectCheckboxProps',
      'onRowSelectionChange',
      'positionToolbarAlertBanner',
      'selectAllMode',
      'selectDisplayMode',
    ])
  }
/>

### Relevant State

<StateOptionsTable onlyOptions={new Set(['rowSelection'])} />

### Enable Row Selection

Selection checkboxes can be enabled with the `enableRowSelection` table option.

```jsx
const table = useMantineReactTable({ columns, data, enableRowSelection: true });
```

### Batch Row Selection

By default, when the user holds down the <kbd>Shift</kbd> key and clicks a row, all rows between the last selected row and the clicked row will be selected. This can be disabled with the `enableBatchRowSelection` table option.

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableRowSelection: true,
  enableBatchRowSelection: false, //disable batch row selection with shift key
});
```

#### Enable Row Selection Conditionally Per Row

You can also enable row selection conditionally per row with the same `enableRowSelection` table option, but with a callback function instead of a boolean.

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableRowSelection: (row) => row.original.age > 18, //disable row selection for rows with age <= 18
});
```

### Access Row Selection State

There a couple of ways to access the selection state. You can either manage the selection state yourself or read it from the table instance.

#### Manage Row Selection State

The row selection state is managed internally by default, but more than likely, you will want to have access to that state yourself. Here is how you can simply get access to the row selection state, specifically.

```tsx
const [rowSelection, setRowSelection] = useState<MRT_RowSelectionState>({}); //ts type available

const table = useMantineReactTable({
  columns,
  data,
  enableRowSelection: true,
  onRowSelectionChange: setRowSelection,
  state: { rowSelection },
});

return <MantineReactTable table={table} />;
```

#### Read Row Selection State or rows from Table Instance

Alternatively, you can read the selection state directly from the `table` instance like so:

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableRowSelection: true,
  renderTopToolbarCustomActions: ({ table }) => (
    <Button
      onClick={() => {
        const rowSelection = table.getState().rowSelection; //read state
        const selectedRows = table.getSelectedRowModel().rows; //or read entire rows
      }}
    >
      Download Selected Users
    </Button>
  ),
});

useEffect(() => {
  //fetch data based on row selection state or something
}, [table.getState().rowSelection]);

return <MantineReactTable table={table} />;
```

#### Useful Row IDs

By default, the `row.id` for each row in the table is simply the index of the row in the table. You can override this and tell Mantine React Table to use a more useful Row ID with the `getRowId` table option. For example, you may want some like this:

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableRowSelection: true,
  getRowId: (originalRow) => originalRow.userId,
});
```

Now as rows get selected, the `rowSelection` state will look like this:

```tsx
{
  "3f25309c-8fa1-470f-811e-cdb082ab9017": true,
  "be731030-df83-419c-b3d6-9ef04e7f4a9f": true,
  ...
}
```

This can be very useful when you are trying to read your selection state and do something with your data as the row selection changes.

<EnableExample />

### Select Row on Row Click

By default, a row can only be selected by either clicking the checkbox or radio button in the `mrt-row-select` column. If you want to be able to select a row by clicking anywhere on the row, you can add your own `onClick` function to a table body row like this:

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableRowSelection: true,
  //clicking anywhere on the row will select it
  mantineTableBodyRowProps: ({ row }) => ({
    onClick: row.getToggleSelectedHandler(),
    style: { cursor: 'pointer' },
  }),
});
```

### Disable Select All

By default, if you enable selection for each row, there will also be a select all checkbox in the header of the checkbox column. It can be hidden with the `enableSelectAll` table option.

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableRowSelection: true,
  enableSelectAll: false,
});
```

### Position or Hide Alert Banner Selection Message

By default, an alert banner will be show as rows are selected. You can use the `positionToolbarAlertBanner` table option to show the alert banner in the top toolbar, bottom toolbar, as an overlay in the table head, or hide it completely.

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableRowSelection: true,
  positionToolbarAlertBanner: 'head-overlay', //show alert banner in bottom toolbar instead of top
});
```

### Alternate Switch and Radio Variants

By default, the selection inputs are Mantine checkboxes, but you can use switch or radio buttons instead with the `selectDisplayMode` table option.

<EnableSwitchExample />

### Single Row Selection

By default, the `enableMultiRowSelection` table option is set to `true`, which means that multiple rows can be selected at once with a checkbox. If you want to only allow a single row to be selected at a time, you can set this table option to `false` and a radio button will be used instead of a checkbox.

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableMultiRowSelection: false, //shows radio buttons instead of checkboxes
  enableRowSelection: true,
  positionToolbarAlertBanner: 'none', //hide alert banner selection message
});
```

<SingleExample />

### Customize Select Checkboxes or Radio Buttons

The selection checkboxes can be customized with the `mantineSelectCheckboxProps` table option. Any prop that can be passed to a Mantine Checkbox component can be specified here. For example, you may want to use a different color for the checkbox, or use some logic to disable certain rows from being selected.

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableRowSelection: true,
  mantineSelectCheckboxProps: {
    color: 'orange',
  },
});
```

<CustomizeExample />

### Manual Row Selection Without Checkboxes

You may have a use case where you want to be able to select rows by clicking them, but you do not want to show any checkboxes or radio buttons. You can do this by implementing a row selection feature yourself, while keeping the `enableRowSelection` table option `false` so that the default selection behavior is disabled.

<ManualExample />

View Extra Storybook **[Examples](https://www.mantine-react-table.dev/?path=/story/features-selection-examples)**
